
#include "i2c.h"
#include "hc32_ll_i2c.h"
#include "hc32_ll_gpio.h"
#include "hc32_ll_fcg.h"
#include "hc32_common.h"

#define I2C_MASTER 1

/* Define I2C unit used for the example */
#define I2C_UNIT                        (CM_I2C1)
/* Define slave device address for example */
#define SLAVE_ADDRESS                   (0x33u)
//#define I2C_10BITS_ADDRESS              (1u)

/* Define port and pin for SDA and SCL */
#define I2C_SCL_PORT                    (GPIO_PORT_A)
#define I2C_SCL_PIN                     (GPIO_PIN_07)
#define I2C_SDA_PORT                    (GPIO_PORT_A)
#define I2C_SDA_PIN                     (GPIO_PIN_06)
#define I2C_GPIO_SCL_FUNC               (GPIO_FUNC_49)
#define I2C_GPIO_SDA_FUNC               (GPIO_FUNC_48)

#define I2C_FCG_USE                     (FCG1_PERIPH_I2C1)
#define TIMEOUT                         (0x1000ul)

/* Define i2c baudrate */
#define I2C_BAUDRATE                    (400000ul)


static en_result_t Master_Init(void)
{
    en_result_t enRet;			
    stc_i2c_init_t stcI2cInit;	
    float32_t fErr;				

    I2C_DeInit(I2C_UNIT);
	
    MEM_ZERO_STRUCT(stcI2cInit);
    stcI2cInit.u32ClockDiv = I2C_CLK_DIV2;
    stcI2cInit.u32Baudrate = I2C_BAUDRATE;
    stcI2cInit.u32SclTime = 0ul;
    enRet = (en_result_t)I2C_Init(I2C_UNIT, &stcI2cInit, &fErr);
 
    I2C_BusWaitCmd(I2C_UNIT, ENABLE);
    return enRet;
}


void i2c1Init(void)
{
    /* Initialize I2C port*/
    GPIO_SetFunc(I2C_SCL_PORT, I2C_SCL_PIN, I2C_GPIO_SCL_FUNC);
    GPIO_SetFunc(I2C_SDA_PORT, I2C_SDA_PIN, I2C_GPIO_SDA_FUNC);

    /* Enable I2C Peripheral*/ 
    FCG_Fcg1PeriphClockCmd(I2C_FCG_USE, ENABLE);
    /* Initialize I2C peripheral and enable function*/

    Master_Init(); 
}


uint8_t i2c3Read(uint8_t u8DevAddr, uint16_t u16MemAddr, uint8_t *pu8Data, uint32_t u32Size)
{
    en_result_t enRet;

    I2C_Cmd(I2C_UNIT, ENABLE);

    I2C_SWResetCmd(I2C_UNIT, ENABLE);
    I2C_SWResetCmd(I2C_UNIT, DISABLE);
    enRet = (en_result_t)I2C_Start(I2C_UNIT,TIMEOUT);
    if(Ok == enRet)
    {
        enRet = (en_result_t)I2C_TransAddr(I2C_UNIT, (uint8_t)u8DevAddr, I2C_DIR_TX, TIMEOUT);
        if(Ok == enRet)
        {
            enRet = (en_result_t)I2C_TransData(I2C_UNIT, (uint8_t *)&u16MemAddr, 1, TIMEOUT);
            if(Ok == enRet)
            {
                enRet = (en_result_t)I2C_Restart(I2C_UNIT,TIMEOUT);
                if(Ok == enRet)
                {
                    if(1ul == u32Size)
                    {	
                        I2C_AckConfig(I2C_UNIT, I2C_NACK);
                    }
                    // enRet = I2C_TransAddr(I2C_UNIT, (uint8_t)u8DevAddr|0x01, I2CDirReceive, TIMEOUT);
                    enRet = (en_result_t)I2C_TransAddr(I2C_UNIT, (uint8_t)u8DevAddr, I2C_DIR_RX, TIMEOUT);
                    if(Ok == enRet)
                    {
                        enRet = (en_result_t)I2C_MasterReceiveDataAndStop(I2C_UNIT, pu8Data, u32Size, TIMEOUT);
                    }
                    I2C_AckConfig(I2C_UNIT, I2C_ACK);
                }
            }
        }
    }
    if(Ok != enRet)
    {
        I2C_Stop(I2C_UNIT,TIMEOUT);
    }
    I2C_Cmd(I2C_UNIT, DISABLE);
	return (enRet==Ok);
}

uint8_t i2c3Write(uint16_t u8DevAddr, uint16_t u16MemAddr, uint8_t *pu8Data, uint32_t u32Size)
{
    en_result_t enRet;

    I2C_Cmd(I2C_UNIT, ENABLE);

    I2C_SWResetCmd(I2C_UNIT, ENABLE);
    I2C_SWResetCmd(I2C_UNIT, DISABLE);
    enRet = (en_result_t)I2C_Start(I2C_UNIT,TIMEOUT);
    if(Ok == enRet)
    {
        enRet = (en_result_t)I2C_TransAddr(I2C_UNIT, u8DevAddr, I2C_DIR_TX, TIMEOUT);

        if(Ok == enRet)
        {
            enRet = (en_result_t)I2C_TransData(I2C_UNIT, (uint8_t *)&u16MemAddr, 1, TIMEOUT);
            if(Ok == enRet)
            {
                enRet = (en_result_t)I2C_TransData(I2C_UNIT, pu8Data, u32Size, TIMEOUT);
            }
        }
    }
    I2C_Stop(I2C_UNIT,TIMEOUT);
    I2C_Cmd(I2C_UNIT, DISABLE);
	
	return (enRet==Ok);
}


